import logging
import json
from bbp.ssdev import SsdevClient, SsdevRpcInvokeError

TYPE = 'type'
CODE = 'code'
NAME = 'name'
ITEMS = 'items'


class DictionaryService(object):
    def __init__(self, client: SsdevClient):
        self.client = client

    def find_all_dict_catalog(self, page_no=0, page_size=100):
        return self.client.invoke('bbp.dicConfig', 'findAllDicCa', page_no, page_size)

    def create_dict_catalog(self, code: str, title: str, parent=''):
        return self.client.invoke('bbp.dicConfig', 'createDicCa',
                                  {"id": "",
                                   "cd": code,
                                   "na": title,
                                   "mnemonicCode": "",
                                   "type": "",
                                   "softId": "",
                                   "des": "",
                                   "py": "",
                                   "wb": "", "zj": "", "parent": parent})

    def query_dict_catalog_by_id(self, ca_id: str):
        return self.client.invoke('bbp.dicConfig', 'queryDicCaById', ca_id)

    def query_dict_catalog_by_code(self, ca_code: str):
        content = self.find_all_dict_catalog()
        for item in content:
            if item['cd'] == ca_code:
                return item
        return None

    def exist_dict_catalog_by_code(self, ca_code: str):
        content = self.find_all_dict_catalog()
        for item in content:
            if item['cd'] == ca_code:
                return True
        return False

    def create_dict(self, code: str, title: str, catalog_id: str = '', dict_type: str = '1'):
        req = {"id": code,
               "cd": code,
               "na": title,
               "dicType": dict_type,
               "ver": None, "dicLevel": 0, "storageType": "1",
               "public": False, "usageType": None, "usageDes": None,
               "des": None, "modifyDate": None, "mnemonicCode": None,
               "py": None, "wb": None, "zj": None,
               "dicCategoryId": catalog_id}
        return self.client.invoke('bbp.dicConfig', 'createDic', req)

    def query_dict(self, code: str):
        try:
            return self.client.invoke('bbp.dicConfig', 'getDictionary', code)
        except SsdevRpcInvokeError as e:
            return None

    def exist_dict(self, code: str):
        exist_rsp = self.query_dict(code)
        return exist_rsp is not None

    def setup_dict(self, code, title, catalog):
        if not self.exist_dict(code):
            self.create_dict(code, title, catalog['id'])
        return self.query_dict(code)

    def load_dict_all_items(self, code, page_no=0, page_size=25):
        return self.client.invoke('bbp.dicConfig', 'loadDicAllItems', code, '', True, page_no, page_size)

    def exist_dict_item(self, dict_code, item_code):
        if self.exist_dict(dict_code):
            exist_all = self.load_dict_all_items(dict_code)['items']
            for item in exist_all:
                if item['cd'] == item_code:
                    return True
            return False
        return False

    # def create_dict_item(self, dict_code, item_code, item_name):
    #     return self.client.invoke('bbp.dicConfig', 'createDictionaryItem', dict_code, item_code, item_name, '')

    def create_dict_item(self, dict_id, item_id, item_code, item_name):
        req_obj = {"leaf": True, "loaded": True, "id": item_id, "index": 1,
                   "depth": 1, "expanded": False, "expandable": True, "checked": None,
                   "cls": "", "iconCls": "", "icon": "", "glyph": "",
                   "root": False, "isLast": True, "isFirst": False, "allowDrop": True,
                   "allowDrag": True, "loading": False, "href": "", "hrefTarget": "",
                   "qtip": "", "qtitle": "", "qshowDelay": 0, "children": None,
                   "visible": True, "key": item_code, "text": item_name, "dicId": dict_id,
                   "cd": item_code, "na": item_name}
        return self.client.invoke('bbp.dicConfig', 'createDicItems', req_obj)

    def setup_dict_item(self, dict_obj, item_code, item_name, item_index):
        if not self.exist_dict_item(dict_obj['id'], item_code):
            self.create_dict_item(dict_obj["id"], 'DicItem-'+str(item_index), item_code, item_name)


class DictionaryConfig(object):
    def __init__(self, service: DictionaryService):
        self.service = service

    def load(self, data):
        json_obj = json.loads(data)
        category_code = json_obj[CODE]
        category_name = json_obj[NAME]

        logging.info("验证是否存字典分类:%s", category_name)
        category = self.service.query_dict_catalog_by_code(category_code)
        if category is None:
            logging.info('不存在字典分类:%s', category_name)
            logging.info('添加字典分类:%s 代码:%s', category_name, category_code)
            self.service.create_dict_catalog(category_code, category_name)
            logging.info('添加字典分类:%s成功', category_name)
            category = self.service.query_dict_catalog_by_code(category_code)

        for item in json_obj[ITEMS]:
            self.enter_dictionary(item, category)

    def enter_dictionary(self, d: dict, category: dict):
        code = d[CODE]
        name = d[NAME]
        items = d[ITEMS]
        logging.info("验证是否存字典:%s", name)
        rsp = self.service.query_dict(code)
        if rsp is None:
            logging.info('不存在字典:%s', name)
            logging.info('添加字典:%s 代码:%s', name, code)
            self.service.setup_dict(code, name, category)
            logging.info('添加字典分类:%s成功', name)

        this_dict = self.service.query_dict(code)

        for index, item in enumerate(items.items()):
            k, v = item
            logging.info('设置字典:%s 项：%s 值:%s', name, k, v)
            self.service.setup_dict_item(this_dict, k, v, index+1)


if __name__ == '__main__':
    import sys
    import os
    import codecs

    logging.basicConfig(stream=sys.stdout, level=logging.INFO)

    Default_tenant_id = 'dzgl'
    Default_username = 'system'
    Default_password = '123'
    Default_bbp_url = 'http://127.0.0.1:8080/bbp-server/'


    def tenant_client() -> SsdevClient:
        tenant = Default_tenant_id
        username = Default_username
        password = Default_password

        client = SsdevClient(Default_bbp_url, Default_bbp_url)
        rsp = client.my_roles(tenant, username, password)
        my_roles = rsp['body']
        token = client.fetch_token(tenant, username, my_roles[0])
        logging.info(token)

        return client


    root = os.path.sep.join(sys.argv[0].split(os.path.sep)[:-2])
    json_file = root + os.path.sep + 'balance-dict.json'
    data = ''

    with codecs.open(json_file, encoding='UTF-8') as f:
        data = f.read()

    service = DictionaryService(tenant_client())
    mc = DictionaryConfig(service)
    mc.load(data)
